package cloudspace.vm.javassist;

import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * The Class MacroDefinition. this class represents a macro definition inside of
 * a javassist configuration file. See Macro class for more information.
 */
public class MacroDefinition extends Macro
{

    /** The command body. */
    String commandBody;


    /**
     * Instantiates a new macro definition.
     * 
     * @param userMacro
     *            the user macro
     * 
     * @throws MalformedMacroBodyException
     *             the malformed macro body exception
     * @throws MalformedMacroNameException
     *             the malformed macro name exception
     * @throws MalformedMacroParametersException
     *             the malformed macro parameters exception
     */
    public MacroDefinition( String userMacro ) throws MalformedMacroException
    {
        super( userMacro, "^[a-zA-Z0-9]+\\(", "\\([^\\)]*\\)" );
        commandBody = getCommmandBody( macro );
    }


    /**
     * This method takes a user macro call and tailors the macro definition.
     * 
     * @param mCall
     *            a macro call to define the macro definition.
     * 
     * @return the tailored command
     * 
     * @throws MacroCallMismatchException
     *             the macro call mismatch exception
     */
    public String getTailoredCommand( MacroCall mCall )
        throws MalformedMacroException
    {
        String tailoredBody = commandBody;
        if ( macroParams.size() != mCall.getNumberOfParams() )
        {
            throw new MalformedMacroException( "Macro call to "
                + mCall.getMacroName() + " has " + mCall.getNumberOfParams()
                + " and the definition has " + getNumberOfParams() );
        }
        Iterator<String> defIter = macroParams.iterator();
        Iterator<String> callIter = mCall.getParameterIterator();

        while ( defIter.hasNext() && callIter.hasNext() )
        {
            String defParam = defIter.next();
            String callParam = callIter.next();
            tailoredBody = tailoredBody.replaceAll( "%\\{\\s*" + defParam
                + "\\s*\\}", Matcher.quoteReplacement( callParam ) );
            tailoredBody = tailoredBody.replaceAll( "%" + defParam,
                Matcher.quoteReplacement( callParam ) );

        }
        return tailoredBody;
    }


    private String getCommmandBody( String macro )
        throws MalformedMacroException
    {
        Pattern commands = Pattern.compile( "\\\".*\\\"" );
        Matcher commandMatcher = commands.matcher( macro );
        String body = "";
        if ( commandMatcher.find() )
        {
            body = commandMatcher.group();
        }
        else
        {
            throw new MalformedMacroException( "Unable to find Macro Body in "
                + macro );
        }
        body = body.trim().substring( 1, body.length() - 1 );
        return body;
    }

}
